<template>
  <div class="webgl-container">
    <div id="webglDom" ref="webglDom">
    </div>
    <div v-if="isShow" :style="clickStyle" class="clickClass">
      <el-row style="font-size:18px;margin-bottom: 30px;">
        <el-col :span="8">
          <div>{{ panelName }}</div>
        </el-col>
        <el-col :span="8">
          <div>容量：100吨</div>
        </el-col>
        <el-col :span="8">
          <div>温度：30°C</div>
        </el-col>
      </el-row>
      <el-row style="font-size:30px;color: aqua;margin-left: 30px;">
        <el-col :span="8">
          <el-image
              src="http://gaohuacloud.com/prod-api/profile/avatar/2022/05/25/5a05b2bd-cbd3-46fe-b065-e1b7e0b0690c.png"
              style="width: 80px; height: 80px"></el-image>
        </el-col>
        <el-col :span="12">
          <div style="margin-top:15px;">40888t</div>
        </el-col>
      </el-row>
      <el-row style="font-size:18px;">
        <el-col :span="12">
          <div>仓高——20米</div>
        </el-col>
        <el-col :span="12">
          <div>梁高——15.8米</div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
// 引入threejs核心模块
import * as THREE from "three"
// 引入OrbitControls
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"
import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js'
// import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
// //长方体 参数：长，宽，高
// var geometry = new THREE.BoxGeometry(100, 100, 100);
// // 球体 参数：半径60  经纬度细分数40,40
// var geometry = new THREE.SphereGeometry(60, 40, 40);
// // 圆柱  参数：圆柱面顶部、底部直径50,50   高度100  圆周分段数
// var geometry = new THREE.CylinderGeometry( 50, 50, 100, 25 );
// // 正八面体
// var geometry = new THREE.OctahedronGeometry(50);
// // 正十二面体
// var geometry = new THREE.DodecahedronGeometry(50);
// // 正二十面体
// var geometry = new THREE.IcosahedronGeometry(50);
var scene = null;
var camera = null;
var renderer = null;
export default {
  name: 'ThreePage',
  data() {
    return {
      // scene: null,
      // camera: null,
      // renderer: null,
      textloader: null,
      width: 0,
      height: 0,
      clickStyle: {
        top: "10px",
        left: "50px",
      },
      isShow: false,
      panelName: '',
      controls: null,
      timer: null,
      num: 1
    }
  },
  watch: {},
  beforeDestroy() {
  },
  mounted() {
    this.$nextTick(this.init());
    window.addEventListener('click', this.onMouseClick, false);
  },
  methods: {
    onMouseClick(event) {
      var raycaster = new THREE.Raycaster()
      var mouse = new THREE.Vector2()
      //通过鼠标点击的位置计算出raycaster所需要的点的位置，以屏幕中心为原点，值的范围为-1到1.
      //通过鼠标点击位置，计算出raycaster所需点的位置，以屏幕为中心点，范围-1到1
      mouse.x = event.clientX / renderer.domElement.clientWidth * 2 - 1;
      mouse.y = -(event.clientY / renderer.domElement.clientHeight * 2) + 1;
      // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
      raycaster.setFromCamera(mouse, camera);

      // 获取raycaster直线和所有模型相交的数组集合
      console.log("666", scene.children);
      let clickMesh = [];
      scene.children.forEach(element => {
        if (element.name.indexOf('粮仓') > -1) {
          element.material.forEach(ele => {
            ele.color.set('#ffffff')
          });
          clickMesh.push(element)

        }
      });
      console.log('clickMesh', clickMesh);
      var intersects = raycaster.intersectObjects(clickMesh);
      let meshs = [];
      console.log("intersects", intersects);
      //将所有的相交的模型的颜色设置为红色，如果只需要将第一个触发事件，那就数组的第一个模型改变颜色即可
      if (intersects.length > 0) {
        console.log("模型实体", intersects[0].object);
        console.log("鼠标点击", event);
        if (intersects[0].object.name) {
          this.panelName = intersects[0].object.name;
          console.log('meshs', meshs);
          intersects[0].object.material.forEach(ele => {
            ele.color.set('#409EFF')
          });
          this.isShow = true;
          this.clickStyle = {
            top: event.clientY + "px",
            left: event.clientX + "px",
          }
        } else {
          this.isShow = false;
        }

      } else {
        this.isShow = false;
      }
    },
    init() {
      // 初始化画布宽高
      const container = this.$refs.webglDom;
      this.width = container.offsetWidth;
      this.height = container.offsetHeight;
      // 场景
      scene = new THREE.Scene();
      scene.fog = new THREE.Fog(0x005577, 1, 2800)
      this.textloader = new THREE.TextureLoader();

      // 相机
      camera = new THREE.PerspectiveCamera(90, this.width / this.height, 0.01, 10000);
      camera.position.set(1200, 320, 1220);
      this.add(camera);
      camera.lookAt(scene.position);

      // 坐标系
      var ip = window.location.host;
      if (ip.split(":")[0] == 'localhost' || ip.split(":")[0] == '192.168.0.111') {
        let axisHelper = new THREE.AxesHelper(1000);
        this.add(axisHelper);
      }
      // 添加灯光
      this.addLight();
      this.addBox(1200, 50, 0);
      this.addCyImage(300, 200, -600, '粮仓02');
      this.addCyImage(650, 200, -600, '粮仓03');
      this.addCyImage(950, 200, -600, '粮仓04');
      this.addCyImage(300, 200, -300, '粮仓11');
      this.addCyImage(650, 200, -300, '粮仓12');
      this.addCyImage(950, 200, -300, '粮仓13');
      this.addCyImage(300, 100, 0, '粮仓05');
      this.addCyImage(650, 100, 0, '粮仓06');
      this.addCyImage(950, 100, 0, '粮仓07');
      this.addCyImage(300, 100, 350, '粮仓08');
      this.addCyImage(650, 100, 350, '粮仓09');
      this.addCyImage(950, 100, 350, '粮仓010');
      this.addCyImage(300, 100, 600, '粮仓14');
      this.addCyImage(650, 100, 600, '粮仓15');
      this.addCyImage(950, 100, 600, '粮仓16');
      this.addFbx();
      //this.addLeftPanel(50,40,0);
      //添加地板
      this.addPanel(600, 0, 0);
      this.addRoadPanel(-300, 0, -300)
      // 初始化一个加载器
      // 渲染器
      renderer = new THREE.WebGLRenderer({
        antialias: true
      })
      renderer.setClearColor(new THREE.Color('#000000'), 1);
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
      renderer.setSize(this.width, this.height);
      document.getElementById("webglDom").appendChild(renderer.domElement);

      // OrbitControls
      new OrbitControls(camera, renderer.domElement);
      this.render();
    },
    addFbx() {
      var loader = new FBXLoader();//创建一个FBX加载器
      loader.load("@/statics/js/fxbData.fbx", function (obj) {
        // console.log(obj);//查看加载后返回的模型对象
        scene.add(obj)
        // 适当平移fbx模型位置
        obj.position.set(1200, 0, 500);
      })
    },
    //添加矩形
    addBox(x, y, z) {
      //创建一个长宽高的盒子模型
      const geometry = new THREE.BoxBufferGeometry(100, 100, 800);
      var materialsbg = [];
      let loader = new THREE.TextureLoader();
      for (var i = 0; i < 7; i++) {
        var material = new THREE.MeshBasicMaterial({
          map: loader.load('statics/topo/office/' + (i + 1) + '.png'),
          side: THREE.FrontSide
        });
        materialsbg[i] = material
      }
      const mesh = new THREE.Mesh(geometry, materialsbg);
      //x、z、y
      mesh.position.set(x, y, z);
      mesh.name = '仓库';
      scene.add(mesh)
    },
    addPanel(x, y, z) {
      // 前面FrontSide  背面：BackSide 双面：DoubleSide
      let loader = new THREE.TextureLoader();
      let texture = loader.load('statics/topo/office/floor3.png')
      let geometry = new THREE.PlaneGeometry(1500, 1500, 32);
      let material = new THREE.MeshBasicMaterial({
        map: texture,  // 使用纹理贴图
        color: '#2a525d',
        side: THREE.DoubleSide  // 两面都渲染
      });
      // 设置阵列
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      // uv两个方向纹理重复数量
      texture.repeat.set(1, 1);
      let plane = new THREE.Mesh(geometry, material);
      plane.name = '底层面板'
      plane.rotateX(Math.PI / 2)
      plane.position.set(x, y, z);
      scene.add(plane);
    },
    addRoadPanel(x, y, z) {
      // 前面FrontSide  背面：BackSide 双面：DoubleSide
      let loader = new THREE.TextureLoader();
      let texture = loader.load('statics/topo/office/road2.png')
      let geometry = new THREE.PlaneGeometry(100, 2500, 32);
      let material = new THREE.MeshBasicMaterial({
        map: texture,  // 使用纹理贴图
        side: THREE.DoubleSide  // 两面都渲染
      });
      // 设置阵列
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      // uv两个方向纹理重复数量
      texture.repeat.set(1, 1);
      let plane = new THREE.Mesh(geometry, material);
      plane.rotateX(Math.PI / 2)
      plane.position.set(x, y, z);
      scene.add(plane);
    },
    //圆柱贴图
    addCyImage(x, z, y, name) {
      // 创建纹理加载器实例
      let cube
      if (y > -300) {
        cube = new THREE.CylinderGeometry(60, 60, 200, 100, 1, false);
      } else {
        cube = new THREE.CylinderGeometry(60, 60, 400, 100, 1, false);
      }
      let cubeMaterials = [
        //side
        new THREE.MeshBasicMaterial({
          map: new THREE.TextureLoader().load('statics/topo/office/d001.png'),
          side: THREE.FrontSide,
          color: '#ffffff'
        }),
        //top
        new THREE.MeshBasicMaterial({side: THREE.DoubleSide, color: '#ffffff'}),
        //bottom
        new THREE.MeshBasicMaterial({side: THREE.DoubleSide, color: '#ffffff'})
      ]
      const mesh = new THREE.Mesh(cube, cubeMaterials);
      mesh.rotateY(-Math.PI / 2 - 0.2)
      mesh.position.set(x, z, y);
      mesh.name = name;
      scene.add(mesh);
    },
    //添加后边界
    addAfterPanel() {
      let geometry = new THREE.PlaneGeometry(1500, 500);
      var ImageLoader = new THREE.ImageLoader();
      // load方法回调函数，按照路径加载图片，返回一个html的元素img对象
      let that = this;
      ImageLoader.load('statics/topo/office/dev3.png', function (img) {
        // image对象作为参数，创建一个纹理对象Texture
        var texture = new THREE.Texture(img);
        // 下次使用纹理时触发更新
        texture.needsUpdate = true;
        var material = new THREE.MeshLambertMaterial({
          map: texture, //设置纹理贴图
        });
        var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
        // mesh.rotateY(Math.PI / 2)
        var group = new THREE.Group();
        group.position.set(0, 100, -750);
        group.add(mesh);
        that.add(group);
      });
    },
    //添加前边界
    addFrontPanel() {
      let geometry = new THREE.PlaneGeometry(1500, 500);
      var ImageLoader = new THREE.ImageLoader();
      // load方法回调函数，按照路径加载图片，返回一个html的元素img对象
      let that = this;
      ImageLoader.load('statics/topo/office/dev3.png', function (img) {
        // image对象作为参数，创建一个纹理对象Texture
        var texture = new THREE.Texture(img);
        // 下次使用纹理时触发更新
        texture.needsUpdate = true;
        var material = new THREE.MeshLambertMaterial({
          map: texture, //设置纹理贴图
        });
        var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
        // mesh.rotateY(Math.PI / 2)
        var group = new THREE.Group();
        group.position.set(0, 100, 750);
        group.add(mesh);
        that.add(group);
      });
    },
    //添加左边界
    addLeftPanel(x, y, z) {
      // 前面FrontSide  背面：BackSide 双面：DoubleSide
      let loader = new THREE.TextureLoader();
      let texture = loader.load('statics/topo/office/road2.png')
      let geometry = new THREE.PlaneGeometry(1500, 100, 102);
      let material = new THREE.MeshBasicMaterial({
        map: texture,  // 使用纹理贴图
        side: THREE.DoubleSide  // 两面都渲染
      });
      // 设置阵列
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      // uv两个方向纹理重复数量
      texture.repeat.set(1, 1);
      let plane = new THREE.Mesh(geometry, material);
      plane.rotateY(Math.PI / 2)
      plane.position.set(x, y, z);
      scene.add(plane);
    },
    //添加右边界
    addRightPanel() {
      let geometry = new THREE.PlaneGeometry(1500, 500);
      var ImageLoader = new THREE.ImageLoader();
      // load方法回调函数，按照路径加载图片，返回一个html的元素img对象
      let that = this;
      ImageLoader.load('statics/topo/office/dev3.png', function (img) {
        // image对象作为参数，创建一个纹理对象Texture
        var texture = new THREE.Texture(img);
        // 下次使用纹理时触发更新
        texture.needsUpdate = true;
        var material = new THREE.MeshLambertMaterial({
          map: texture, //设置纹理贴图
        });
        var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
        mesh.rotateY(Math.PI / 2)
        var group = new THREE.Group();
        group.position.set(750, 100, 0);
        group.add(mesh);
        that.add(group);
      });
    },
    //添加球形
    addSphere(x, y, z) {
      //创建一个长宽高的盒子模型
      const geometry = new THREE.SphereGeometry(x, y, z);
      const material = new THREE.MeshPhongMaterial({
        color: 0xff0000
      });
      const mesh = new THREE.Mesh(geometry, material);
      console.log('mesh', mesh);
      mesh.position.set(150, 0, 0);
      var group = new THREE.Group();
      group.position.set(150, 0, 0);
      group.add(mesh);
      this.add(group);
      console.log('本地坐标', mesh.position);
      var worldPosition = new THREE.Vector3();
      mesh.getWorldPosition(worldPosition);
      console.log('世界坐标', worldPosition);
    },
    //添加圆柱
    addCylinder() {
      const geometry = new THREE.CylinderGeometry(100, 100, 500, 100, 1, false);
      const material = new THREE.MeshPhongMaterial({
        color: '#ffffff'
      });
      const mesh = new THREE.Mesh(geometry, material);
      console.log('mesh', mesh);
      mesh.position.set(0, 0, 0);
      var group = new THREE.Group();
      group.position.set(0, 0, 0);
      group.add(mesh);
      this.add(group);
      console.log('本地坐标', mesh.position);
      var worldPosition = new THREE.Vector3();
      mesh.getWorldPosition(worldPosition);
      console.log('世界坐标', worldPosition);
    },
    addLight() {
      // 环境光
      const light = new THREE.AmbientLight(0xffffff, 0.5); // soft white light
      this.add(light);

      // // 平行光源
      const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
      directionalLight.position.set(200, 600, 200);
      this.add(directionalLight);
    },
    add(obj) {
      scene.add(obj);
    },
    render() {
      renderer.render(scene, camera);
      requestAnimationFrame(this.render);
    }
  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#webglDom,
.webgl-container {
  width: 100%;
  height: 100%;
  overflow: hidden;
  padding: 2px;
}

.clickClass {
  position: fixed;
  color: aliceblue;
  padding: 40px;
  width: 400px;
  height: 250px;
  /* background-color: #7f7f7f; */
  background-image: url("http://gaohuacloud.com/prod-api/profile/avatar/2022/07/22/panelThree_20220722104950A023.png");
  background-size: cover;
}
</style>

